﻿/**************************************************************************
* 文件名称: traverse__VA_ARGS__mocro.h
* 文件标识:
* 内容摘要: 自定义的一些通用的宏，用于遍历或迭代可变参宏的所有参数，可以对每个参数实现各种
*          操作。从而实现编译期间的一些高级特性，如编译时多态，宏的重载等功能
* 其它说明:
* 当前版本: V3.0
* 作   者: 李荣业
* 完成日期: 2015-5-25 12:54:20
* 修改记录1:
*     修改日期:
*     版 本 号:
*     修 改 人:
*     修改内容:
**************************************************************************/

#ifndef TRAVERSE__VA_ARGS__MOCRO_H
#define TRAVERSE__VA_ARGS__MOCRO_H

/***************************** 计算可变参宏中可变参数的个数 begin *****************************/
#define MSVC_EXPAND(...) __VA_ARGS__
#define eatComma(...) , ##__VA_ARGS__

#define PP_NARG(...) PP_NARG_(eatComma(__VA_ARGS__), PP_RSEQ_N())

#define PP_NARG_(...) MSVC_EXPAND(PP_ARG_N(__VA_ARGS__))

#define PP_ARG_N( \
                  _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
                  _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
                  _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
                  _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
                  _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
                  _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
                  _61,_62,_63,N,...) N

#define PP_RSEQ_N() \
    62,61,60, \
    59,58,57,56,55,54,53,52,51,50, \
    49,48,47,46,45,44,43,42,41,40, \
    39,38,37,36,35,34,33,32,31,30, \
    29,28,27,26,25,24,23,22,21,20, \
    19,18,17,16,15,14,13,12,11,10, \
    9, 8, 7, 6, 5, 4, 3, 2, 1, 0

#define MANY     MANY
#define ONE      ONE
#define ZERO     ZERO

#define CHECK_MACRO_PARAMS_COUNT(...) \
    CHECK_MACRO_PARAMS_COUNT_( , ##__VA_ARGS__, CHECK_PARAMS_COUNT_RSEQ_N())

#define CHECK_MACRO_PARAMS_COUNT_(...) CHECK_PARAMS_COUNT_ARG_N(__VA_ARGS__)

#define CHECK_PARAMS_COUNT_ARG_N( \
                                  _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
                                  _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
                                  _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
                                  _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
                                  _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
                                  _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
                                  _61,_62,_63,N,...) N

#define CHECK_PARAMS_COUNT_RSEQ_N() \
    MANY,MANY,MANY,MANY,MANY,MANY,MANY,MANY,MANY,MANY,  \
    MANY,MANY,MANY,MANY,MANY,MANY,MANY,MANY,MANY,MANY,  \
    MANY,MANY,MANY,MANY,MANY,MANY,MANY,MANY,MANY,MANY,  \
    MANY,MANY,MANY,MANY,MANY,MANY,MANY,MANY,MANY,MANY,  \
    MANY,MANY,MANY,MANY,MANY,MANY,MANY,MANY,MANY,MANY,  \
    MANY,MANY,MANY,MANY,MANY,MANY,MANY,MANY,MANY,MANY,  \
    MANY,ONE,ZERO
/***************************** 计算可变参宏中可变参数的个数 end *****************************/

#define STR(arg)      STR1(arg)
#define STR1(arg)     STR2(arg)
#define STR2(arg)     #arg

#define CONNECT_2_ARGS2(arg1, arg2)    arg1##arg2
#define CONNECT_2_ARGS1(arg1, arg2)    CONNECT_2_ARGS2(arg1, arg2)
#define CONNECT_2_ARGS(arg1, arg2)     CONNECT_2_ARGS1(arg1, arg2)

#define REMOVE_BRACKETS1(...) __VA_ARGS__
#define REMOVE_BRACKETS(args) REMOVE_BRACKETS1 args

/***************************** 遍历或迭代可变参宏的所有参数 begin *****************************/
#define FOR_EACH_1(what, paramInfo, connectInfo, x)    \
    what(x, paramInfo)

#define FOR_EACH_2(what, paramInfo, connectInfo, x, ...)    \
    what(x, paramInfo)\
    connectInfo \
    MSVC_EXPAND(FOR_EACH_1(what, paramInfo, connectInfo, ##__VA_ARGS__))

#define FOR_EACH_3(what, paramInfo, connectInfo, x, ...)    \
    what(x, paramInfo)\
    connectInfo \
    MSVC_EXPAND(FOR_EACH_2(what, paramInfo, connectInfo, ##__VA_ARGS__))

#define FOR_EACH_4(what, paramInfo, connectInfo, x, ...)    \
    what(x, paramInfo)\
    connectInfo \
    MSVC_EXPAND(FOR_EACH_3(what, paramInfo, connectInfo, ##__VA_ARGS__))

#define FOR_EACH_5(what, paramInfo, connectInfo, x, ...)    \
    what(x, paramInfo)\
    connectInfo \
    MSVC_EXPAND(FOR_EACH_4(what, paramInfo, connectInfo, ##__VA_ARGS__))

#define FOR_EACH_6(what, paramInfo, connectInfo, x, ...)    \
    what(x, paramInfo)\
    connectInfo \
    MSVC_EXPAND(FOR_EACH_5(what, paramInfo, connectInfo, ##__VA_ARGS__))

#define FOR_EACH_7(what, paramInfo, connectInfo, x, ...)    \
    what(x, paramInfo)\
    connectInfo \
    MSVC_EXPAND(FOR_EACH_6(what, paramInfo, connectInfo, ##__VA_ARGS__))

#define FOR_EACH_8(what, paramInfo, connectInfo, x, ...)    \
    what(x, paramInfo)\
    connectInfo \
    MSVC_EXPAND(FOR_EACH_7(what, paramInfo, connectInfo, ##__VA_ARGS__))

#define FOR_EACH_9(what, paramInfo, connectInfo, x, ...)    \
    what(x, paramInfo)\
    connectInfo \
    MSVC_EXPAND(FOR_EACH_8(what, paramInfo, connectInfo, ##__VA_ARGS__))

#define FOR_EACH_10(what, paramInfo, connectInfo, x, ...)    \
    what(x, paramInfo)\
    connectInfo \
    MSVC_EXPAND(FOR_EACH_9(what, paramInfo, connectInfo, ##__VA_ARGS__))

#define FOR_EACH_11(what, paramInfo, connectInfo, x, ...)    \
    what(x, paramInfo)\
    connectInfo \
    MSVC_EXPAND(FOR_EACH_10(what, paramInfo, connectInfo, ##__VA_ARGS__))

#define FOR_EACH_12(what, paramInfo, connectInfo, x, ...)    \
    what(x, paramInfo)\
    connectInfo \
    MSVC_EXPAND(FOR_EACH_11(what, paramInfo, connectInfo, ##__VA_ARGS__))

#define FOR_EACH_13(what, paramInfo, connectInfo, x, ...)    \
    what(x, paramInfo)\
    connectInfo \
    MSVC_EXPAND(FOR_EACH_12(what, paramInfo, connectInfo, ##__VA_ARGS__))

#define FOR_EACH_14(what, paramInfo, connectInfo, x, ...)    \
    what(x, paramInfo)\
    connectInfo \
    MSVC_EXPAND(FOR_EACH_13(what, paramInfo, connectInfo, ##__VA_ARGS__))

#define FOR_EACH_15(what, paramInfo, connectInfo, x, ...)    \
    what(x, paramInfo)\
    connectInfo \
    MSVC_EXPAND(FOR_EACH_14(what, paramInfo, connectInfo, ##__VA_ARGS__))

#define FOR_EACH_16(what, paramInfo, connectInfo, x, ...)    \
    what(x, paramInfo)\
    connectInfo \
    MSVC_EXPAND(FOR_EACH_15(what, paramInfo, connectInfo, ##__VA_ARGS__))

#define FOR_EACH_17(what, paramInfo, connectInfo, x, ...)    \
    what(x, paramInfo)\
    connectInfo \
    MSVC_EXPAND(FOR_EACH_16(what, paramInfo, connectInfo, ##__VA_ARGS__))

#define FOR_EACH_18(what, paramInfo, connectInfo, x, ...)    \
    what(x, paramInfo)\
    connectInfo \
    MSVC_EXPAND(FOR_EACH_17(what, paramInfo, connectInfo, ##__VA_ARGS__))

#define FOR_EACH_19(what, paramInfo, connectInfo, x, ...)    \
    what(x, paramInfo)\
    connectInfo \
    MSVC_EXPAND(FOR_EACH_18(what, paramInfo, connectInfo, ##__VA_ARGS__))

#define FOR_EACH_20(what, paramInfo, connectInfo, x, ...)    \
    what(x, paramInfo)\
    connectInfo \
    MSVC_EXPAND(FOR_EACH_19(what, paramInfo, connectInfo, ##__VA_ARGS__))

#define FOR_EACH_21(what, paramInfo, connectInfo, x, ...)    \
    what(x, paramInfo)\
    connectInfo \
    MSVC_EXPAND(FOR_EACH_20(what, paramInfo, connectInfo, ##__VA_ARGS__))

#define FOR_EACH_22(what, paramInfo, connectInfo, x, ...)    \
    what(x, paramInfo)\
    connectInfo \
    MSVC_EXPAND(FOR_EACH_21(what, paramInfo, connectInfo, ##__VA_ARGS__))

#define FOR_EACH_23(what, paramInfo, connectInfo, x, ...)    \
    what(x, paramInfo)\
    connectInfo \
    MSVC_EXPAND(FOR_EACH_22(what, paramInfo, connectInfo, ##__VA_ARGS__))

#define FOR_EACH_24(what, paramInfo, connectInfo, x, ...)    \
    what(x, paramInfo)\
    connectInfo \
    MSVC_EXPAND(FOR_EACH_23(what, paramInfo, connectInfo, ##__VA_ARGS__))

#define FOR_EACH_25(what, paramInfo, connectInfo, x, ...)    \
    what(x, paramInfo)\
    connectInfo \
    MSVC_EXPAND(FOR_EACH_24(what, paramInfo, connectInfo, ##__VA_ARGS__))

#define FOR_EACH_26(what, paramInfo, connectInfo, x, ...)    \
    what(x, paramInfo)\
    connectInfo \
    MSVC_EXPAND(FOR_EACH_25(what, paramInfo, connectInfo, ##__VA_ARGS__))

#define FOR_EACH_27(what, paramInfo, connectInfo, x, ...)    \
    what(x, paramInfo)\
    connectInfo \
    MSVC_EXPAND(FOR_EACH_26(what, paramInfo, connectInfo, ##__VA_ARGS__))

#define FOR_EACH_28(what, paramInfo, connectInfo, x, ...)    \
    what(x, paramInfo)\
    connectInfo \
    MSVC_EXPAND(FOR_EACH_27(what, paramInfo, connectInfo, ##__VA_ARGS__))

#define FOR_EACH_29(what, paramInfo, connectInfo, x, ...)    \
    what(x, paramInfo)\
    connectInfo \
    MSVC_EXPAND(FOR_EACH_28(what, paramInfo, connectInfo, ##__VA_ARGS__))

#define FOR_EACH_30(what, paramInfo, connectInfo, x, ...)    \
    what(x, paramInfo)\
    connectInfo \
    MSVC_EXPAND(FOR_EACH_29(what, paramInfo, connectInfo, ##__VA_ARGS__))

#define FOR_EACH_31(what, paramInfo, connectInfo, x, ...)    \
    what(x, paramInfo)\
    connectInfo \
    MSVC_EXPAND(FOR_EACH_30(what, paramInfo, connectInfo, ##__VA_ARGS__))

#define FOR_EACH_32(what, paramInfo, connectInfo, x, ...)    \
    what(x, paramInfo)\
    connectInfo \
    MSVC_EXPAND(FOR_EACH_31(what, paramInfo, connectInfo, ##__VA_ARGS__))


#define FOR_EACH_(N, what, paramInfo, connectInfo, x, ...)  CONNECT_2_ARGS(FOR_EACH_, N)(what, paramInfo, connectInfo, x, ##__VA_ARGS__)

#ifdef _MSC_VER   //for MSVC编译器
#   define leftBracket     (
#   define PP_NARG1(x, ...)   PP_NARG leftBracket x, ##__VA_ARGS__)
#   define FOR_EACH(what, paramInfo, connectInfo, x, ...)      FOR_EACH_(PP_NARG1(lirongye, ##__VA_ARGS__), what, paramInfo, connectInfo, x, ##__VA_ARGS__)
#elif defined(__GNUC__) || defined(__MINGW32__)   //for GCC/g++ MinGW编译器
#   define FOR_EACH(what, paramInfo, connectInfo, x, ...)      FOR_EACH_(PP_NARG(lirongye, ##__VA_ARGS__), what, paramInfo, connectInfo, x, ##__VA_ARGS__)
#else
#   error FOR_EACH Error!! Compiler type is not supported
#endif

/***************************** 遍历或迭代可变参宏的所有参数 end *****************************/

#endif  // TRAVERSE__VA_ARGS__MOCRO_H
